﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using Collab.Services.Remote;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.ServiceModel.Channels;
using Collab.Services.Remote.Contracts;

namespace Collab.Services.ConsoleHost
{
    class Program
    {
        static void Main(string[] args)
        {

            EndpointAddress ep = new EndpointAddress("net.tcp://localhost:8000");
            using (ServiceHost host = new ServiceHost(typeof(RemoteCollaborationService)))
            {
                NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);
                
                var elems = binding.CreateBindingElements();
                foreach (var item in elems)
                {
                    if (item is TcpTransportBindingElement)
                        (item as TcpTransportBindingElement).TeredoEnabled = true;
                }
                CustomBinding custBind = new CustomBinding(elems);
                host.Description.Endpoints.Clear();
                host.AddServiceEndpoint(typeof(IRemoteCollaborationService), custBind, "net.tcp://localhost:8000");
                host.Faulted += (sender, e) => Console.WriteLine("ServiceHost has faulted. Restart the service.");
                host.Open();
                
                Console.WriteLine(String.Format("ServiceHost now running on address." + GetTeredoIPv6Address().ToString()));

                Console.ReadLine();
            }

            Console.ReadLine();
        }

        private static IPAddress GetTeredoIPv6Address()
        {
            if (!NetworkInterface.GetIsNetworkAvailable())
                throw new ApplicationException("Network is not available!");

            if (!Socket.OSSupportsIPv6)
                throw new ApplicationException("IPv6 not enabled!");

            NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();

            if (nics == null || nics.Length == 0)
                throw new ApplicationException("No network interfaces found.");

            foreach (NetworkInterface adapter in nics)
            {
                if (!adapter.Supports(NetworkInterfaceComponent.IPv6))
                    continue;

                if (!adapter.Description.Contains("Teredo"))
                    continue;

                IPInterfaceProperties props = adapter.GetIPProperties();

                foreach (UnicastIPAddressInformation uiai in props.UnicastAddresses)
                {
                    IPAddress addr = uiai.Address;

                    if (addr.IsIPv6LinkLocal || addr.IsIPv6SiteLocal)
                        continue;

                    return addr;
                }
            }

            throw new ApplicationException("Teredo adapter is not found!");
        }
    }
}
